#include <tfparser.h>
#include <cstring>
#include <cstdlib>
#include <assert.h>

vector<double> TextFileParser::GetDoubleParamsArray(int count) {
	vector<double> nums;
	double param;
	string format;
	int res;
	for (int i=0; i<count; i++) {
		format = fmt+"%lf";
		res = sscanf(params, format.c_str(), &param);
		if ((res == 0) || (res == EOF)) {
			nums.clear();
			return nums;
		}
		
		fprintf(fOut,"%E ", param);
		nums.push_back(param);
		fmt += "%*lf";
	}

	return nums;
}

vector<int> TextFileParser::GetIntParamsArray(int count) {
	vector<int> nums;
	int param;
	string format;
	int res;
	for (int i=0; i<count; i++) {
		format = fmt+"%d";
		res = sscanf(params, format.c_str(), &param);
		if ((res == 0) || (res == EOF)) {
			nums.clear();
			return nums;
		}
		
		fprintf(fOut,"%d ", param);
		nums.push_back(param);
		fmt += "%*d";
	}
	return nums;
}

int TextFileParser::GetInterpolationFunc(func_points_t* func) {
	int rc1;
	// Считаем количество элементов в таблице.
	string format = fmt+"%d";
	int count = NULL_VALUE;
	if (sscanf(params, format.c_str(), &count) == 0)
		return NULL_VALUE;
	 fprintf(fOut, "%d\n", count);
	assert(count != NULL_VALUE);
	// Создаём табличное представление функции.
	func->count = count;
	func->x = new double[func->count];
	assert(func->x != 0);
	func->y = new double[func->count];
	assert(func->y != 0);
	// Считать строку со значением аргумента.
	char* res = fgets(params, COMMENT_MAX_LEN, fIn);
	if (res == 0)
		return NULL_VALUE;
	// Прочитать значения аргумента в таблицу.
	fmt = "%*s";
	format.clear();
	rc1 = sscanf(params, "%s", command);
	if ((rc1 == 0) || (rc1 == EOF))
		return NULL_VALUE;
	 fprintf(fOut, "%s ", command);
	vector<double>d = GetDoubleParamsArray(func->count);
	if (d.size() == 0)
		return NULL_VALUE;
	for (int i=0; i<func->count; i++)
		func->x[i] = d[i];
	 fprintf(fOut, "\n");
	// Считать строку со значением функции.
	res = fgets(params, COMMENT_MAX_LEN, fIn);
	if (res == 0)
		return NULL_VALUE;
	fmt = "%*s";
	format.clear();
	rc1 = sscanf(params, "%s", command);
	if ((rc1 == 0) || (rc1 == EOF))
		return NULL_VALUE;
	 fprintf(fOut, "%s ", command);
	d = GetDoubleParamsArray(func->count);
	if (d.size() == 0)
		return NULL_VALUE;
	for (int i=0; i<func->count; i++)
		func->y[i] = d[i];
	
	return 0;
}

vector<string> TextFileParser::GetStringParamsArray(int count) {
	vector<string> nums;
	char param[COMMENT_MAX_LEN];
	string format;
	int res;
	for (int i=0; i<count; i++) {
		format = fmt+"%s";
		res = sscanf(params, format.c_str(), param);
		if ((res == 0) || (res == EOF)) {
			nums.clear();
			return nums;
		}
		
		fprintf(fOut,"%s ", param);
		nums.push_back(param);
		fmt += "%*s";
	}

	return nums;
}

char* TextFileParser::GetNextCommand() {
	if (!fmt.empty()) {
		fmt.clear();
		fprintf(fOut, "\n");
	}
	for(;;) {
		char* res = fgets(params, COMMENT_MAX_LEN, fIn);
		if (res == 0)
			return 0;
		if (strlen(res) <= 1)
			continue;
		int rc = sscanf(params, "%s", command);
		assert((rc != 0) && (rc != EOF));
		fprintf(fOut, "%s ", command);
		if (strcmp(command, "#") == 0) {
			fprintf(fOut, "%s", &params[1]);
			continue;
		}
		fmt+="%*s";
		return command;
	}
}

double TextFileParser::GetNextDouble() {
	vector<double> i = GetDoubleParamsArray(1);
	if (i.size() > 0)
		return i[0];
	else
		return NULL_VALUE;
}

int TextFileParser::GetNextInt() {
	vector<int> i = GetIntParamsArray(1);
	if (i.size() > 0)
		return i[0];
	else
		return NULL_VALUE;
}

int TextFileParser::GetNextString(string* str) {
	vector<string> i = GetStringParamsArray(1);
	if (i.size() > 0) {
		*str = i[0];
		return 0;
	} else
		return NULL_VALUE;
}

TextFileParser::TextFileParser(FILE* fin, FILE* fout) {
	if (fout == 0)
		fOut = stdout;
	else
		fOut = fout;
	assert(fin != 0);	
	fIn = fin;
	fmt.empty();
	command[0] = '\0';
	
	return;
}

TextFileParser::~TextFileParser() {
}
